#include <iostream>
#include <cstdlib>

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2

typedef int Status;
typedef int ElemType;
typedef struct QNode{
	ElemType data;
	struct QNode *next;
}QNode;

class LinkQueue
{
private:
	QNode *front, *rear;
	
public:
	LinkQueue();
	Status InitQueue();
	Status DestroyQueue();
	Status ClearQueue();
	bool QueueEmpty();
	int QueueLength();
	Status GetHead(ElemType &e);
	Status EnQueue(ElemType e);
	Status DeQueue(ElemType &e);
	Status QueueTraverse(Status (*func)(ElemType e));
};

LinkQueue::LinkQueue()
{
	Status st = this->InitQueue();
	if(st != OK)
		exit(ERROR);
}

Status LinkQueue::InitQueue()
{
	this->front = this->rear = (QNode *)malloc(sizeof(QNode));
	if(!this->front)
		exit(OVERFLOW);
	this->front->next = NULL;
	return OK;
}

Status LinkQueue::DestroyQueue()
{
	while(this->front)
	{
		this->rear = this->front->next;
		free(this->front);
		this->front = this->rear;
	}
	return OK;
}

Status LinkQueue::ClearQueue()
{
	QNode *p = this->front, *q;
	while(p)
	{
		q = p;
		p = p->next;
		free(q);
	}
	this->rear = this->front;
	return OK;
}

bool LinkQueue::QueueEmpty()
{
	return (this->front) == (this->rear);
}

int LinkQueue::QueueLength()
{
	int len = 0;
	QNode *p = this->front;
	if(!p)
		exit(ERROR);
	while(p->next)
	{
		p = p->next;
		len++;
	}
	return len;
}

Status LinkQueue::GetHead(ElemType &e)
{
	if(this->front == this->rear)
		return ERROR;
	e = this->front->next->data;
	return OK;
}

Status LinkQueue::EnQueue(ElemType e)
{
	QNode *p;
	p = (QNode *)malloc(sizeof(QNode));
	if(!p)
		exit(OVERFLOW);
	p->data = e;
	p->next = NULL;
	this->rear->next = p;
	this->rear = p;
	return OK;
}

Status LinkQueue::DeQueue(ElemType &e)
{
	QNode *p;
	if(this->front == this->rear)
		return ERROR;
	p = this->front->next;
	e = p->data;
	this->front->next = p->next;
	if(this->rear == p)
		this->rear = this->front;
	free(p);
	return OK;
}

Status LinkQueue::QueueTraverse(Status (*func)(ElemType e))
{
	Status st = OK;
	QNode *p = this->front->next;
	while(p && (st == OK))
	{
		st = (*func)(p->data);
		p = p->next;
	}
	return st;
}
